@tool
class_name BaseRoom
extends Node2D

#region 编辑器方法
@export_tool_button("添加Special_ReplaceTile")
var add_special_replace_tile_action = add_special_replace_tile
func add_special_replace_tile():
	for layer in layers:
		var tile_set:TileSet = layer.tile_set
		if tile_set and not tile_set.has_custom_data_layer_by_name(Constant.REPLACE_TILE_LAYER_NAME):
			tile_set.add_custom_data_layer(-1)
			tile_set.set_custom_data_layer_name(tile_set.get_custom_data_layers_count() - 1,Constant.REPLACE_TILE_LAYER_NAME)
			tile_set.set_custom_data_layer_type(tile_set.get_custom_data_layers_count() - 1,TYPE_INT)
#endregion

@export var layers_node:Node2D
@export var layers:Array[TileMapLayer]
# 开启生成Enemy的最大怪物数量
@export var start_spawn_task_max_enemy_amount:int = 0
@export var birth_area:SpawnArea
@export var areas:Array[SpawnArea]
@export var room_special_layer_infos:Array[RoomSpecialLayerInfo]
@export var doors:Node2D
var room_info:RoomInfo
var room_args:Dictionary
var room_idx:int
var cur_room_status:GameEnum.RoomStatus
var inited:bool = false
var cur_enemies:Array = []
var cur_items:Array = []
var cur_doors:Array[BaseDoor] = []
var cur_valid_spawn_task_index:int = 0
var _spawn_task_tween:Tween = null
var room_special_tile_map_layer_replacer:RoomSpecialTileMapLayerReplacer = RoomSpecialTileMapLayerReplacer.new()
var room_special_layer_info_dict:Dictionary = {}

signal on_enemey_amount_changed(amount:int)

func init_room(room_info:RoomInfo,room_args:Dictionary):
	self.room_info = room_info
	self.room_args = room_args
	global_position = room_args.get("Pos",Vector2.ZERO)
	self.room_idx = room_args.get("Index",-1)
	for info in room_special_layer_infos:
		if not room_special_layer_info_dict.has(info.replace_room_tile_info.special_replae_id):
			room_special_layer_info_dict.set(info.replace_room_tile_info.special_replae_id,info)
	#on_enemey_amount_changed.connect(check_enemy_amount)
	paint_room()
	## TODO 初始化门
	init_door()
	## TODO 初始化玩家及其随从
	#cur_room_status = GameEnum.RoomStatus.Arrived
	## 开启生成任务
	#start_spawn_task()
func get_room_special_layer_info_by_replace_tile_id(special_replae_id:int) -> RoomSpecialLayerInfo:
	return room_special_layer_info_dict.get(special_replae_id)
func get_birth_pos() -> Vector2:
	if birth_area:
		var spawn_pos = birth_area.get_spawn_point(GamePlayerSystem.player,self)
		if spawn_pos:
			return spawn_pos + global_position
		else:
			push_error("没法找到用于生成玩家的位置！")
	return global_position
func paint_room():
	replace_all_special_layers()
	bake_all_navigation_polygen()
	update_mini_map()
func update_mini_map():
	# TODO 更新小地图
	pass
## 初始化门
func init_door():
	for child in doors.get_children():
		if child is BaseDoor:
			child.init(self,)
			cur_doors.append(child)
## TODO 获得邻居房间
func replace_all_special_layers():
	# 执行所有特殊TileMapLayer的替换
	var items:Array[Node2D] = []
	for layer in layers:
		room_special_tile_map_layer_replacer.init(self,layer)
		items.append_array(room_special_tile_map_layer_replacer.replace_all())
	for item in items:
		add_item(item)
func bake_all_navigation_polygen():
	for child in get_children():
		if child is NavigationRegion2D:
			child.bake_navigation_polygon(true)
func start_spawn_task():
	if not _spawn_task_tween:
		_spawn_task_tween = areas[cur_valid_spawn_task_index].get_spawn_task(self,create_item)
		_spawn_task_tween.tween_callback(func ():
			_spawn_task_tween = null
			cur_valid_spawn_task_index += 1
			if cur_valid_spawn_task_index >= areas.size():
				end_spawn_task()
			else:
				on_enemey_amount_changed.emit(cur_enemies.size())
			)
func end_spawn_task():
	if _spawn_task_tween:
		_spawn_task_tween.kill()
		_spawn_task_tween = null
	cur_valid_spawn_task_index = areas.size() - 1
func check_room_status():
	if cur_room_status == GameEnum.RoomStatus.NotArrived:
		return
	elif cur_room_status == GameEnum.RoomStatus.Arrived:
		if check_room_end():
			cur_room_status = GameEnum.RoomStatus.End
			destroy_room()
func check_room_end() -> bool:
	# 检查还有无敌对阵营的Enemy
	if cur_valid_spawn_task_index >= areas.size() and not cur_enemies.any(func (enemy):return enemy.get_component_by_name("CampComponent").cur_camp == GameEnum.Camp.Hostile):
		return true
	return false
func destroy_room():
	on_enemey_amount_changed.disconnect(check_enemy_amount)
	end_spawn_task()
	queue_free()
func create_item():
	var item = areas[cur_valid_spawn_task_index].get_item().instantiate()
	var spwan_pos = areas[cur_valid_spawn_task_index].get_spawn_point(item,self)
	if spwan_pos:
		item.global_position = global_position + spwan_pos
		add_child(item)
		# TODO 根据item类型初始化
		item.init()
		add_item(item)
	else:
		printerr("物体{"+item.name+"}生成失败：没法找到可用的生成位置！")
func add_item(item,is_enemy:bool = false):
	if is_enemy:
		cur_enemies.append(item)
		on_enemey_amount_changed.emit(cur_enemies.size())
	else:
		cur_items.append(item)
	pass
func remove_item(item,is_enemy:bool = false):
	if is_enemy:
		cur_enemies.erase(item)
		on_enemey_amount_changed.emit(cur_enemies.size())
	else:
		cur_items.erase(item)
func check_enemy_amount(amount:int):
	if amount <= start_spawn_task_max_enemy_amount and not _spawn_task_tween:
		start_spawn_task()

func _draw() -> void:
	if birth_area:
		if birth_area.spawn_area_type == GameEnum.SpawnAreaType.Circle:
			draw_arc(position + birth_area.center,birth_area.radius,0,TAU,30,Color.RED)
	for area in areas:
		if area.spawn_area_type == GameEnum.SpawnAreaType.Circle:
			draw_arc(position + area.center,area.radius,0,TAU,30,Color.BLUE)
		elif area.spawn_area_type == GameEnum.SpawnAreaType.Rectangle:
			draw_rect(Rect2(position + area.center, area.size),Color.BLUE)
